#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <io.h>
#include <fcntl.h>
#include "s2t.h"

// 动态数组结构
typedef struct {
    wchar_t **file_names;
    wchar_t **rel_paths;
    int count;
    int capacity;
} FileArray;

// 初始化文件数组
void init_file_array(FileArray *arr, int initial_capacity) {
    arr->count = 0;
    arr->capacity = initial_capacity;
    arr->file_names = (wchar_t **)malloc(initial_capacity * sizeof(wchar_t *));
    arr->rel_paths = (wchar_t **)malloc(initial_capacity * sizeof(wchar_t *));
}

// 向文件数组添加条目
void add_to_file_array(FileArray *arr, const wchar_t *file_name, const wchar_t *rel_path) {
    if (arr->count >= arr->capacity) {
        arr->capacity *= 2;
        arr->file_names = (wchar_t **)realloc(arr->file_names, arr->capacity * sizeof(wchar_t *));
        arr->rel_paths = (wchar_t **)realloc(arr->rel_paths, arr->capacity * sizeof(wchar_t *));
    }
    
    arr->file_names[arr->count] = _wcsdup(file_name);
    arr->rel_paths[arr->count] = _wcsdup(rel_path);
    arr->count++;
}

// 释放文件数组内存
void free_file_array(FileArray *arr) {
    for (int i = 0; i < arr->count; i++) {
        free(arr->file_names[i]);
        free(arr->rel_paths[i]);
    }
    free(arr->file_names);
    free(arr->rel_paths);
    arr->count = 0;
    arr->capacity = 0;
}

// 将反斜杠替换为正斜杠
void normalize_path(wchar_t *path) {
    for (wchar_t *p = path; *p; p++) {
        if (*p == L'\\') *p = L'/';
    }
}

// 递归扫描目录
void scan_directory(const wchar_t *base_path, const wchar_t *current_path, FileArray *arr) {
    wchar_t full_path[MAX_PATH];
    if (wcslen(current_path)) {
        swprintf(full_path, MAX_PATH, L"%s\\%s", base_path, current_path);
    } else {
        wcscpy_s(full_path, MAX_PATH, base_path);
    }
    
    WIN32_FIND_DATAW find_data;
    wchar_t search_path[MAX_PATH];
    swprintf(search_path, MAX_PATH, L"%s\\*", full_path);
    
    HANDLE hFind = FindFirstFileW(search_path, &find_data);
    if (hFind == INVALID_HANDLE_VALUE) {
        return;
    }
    
    do {
        if (wcscmp(find_data.cFileName, L".") == 0 || wcscmp(find_data.cFileName, L"..") == 0) {
            continue;
        }
        
        wchar_t rel_path[MAX_PATH];
        if (wcslen(current_path)) {
            swprintf(rel_path, MAX_PATH, L"%s/%s", current_path, find_data.cFileName);
        } else {
            wcscpy_s(rel_path, MAX_PATH, find_data.cFileName);
        }
        
        if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            scan_directory(base_path, rel_path, arr);
        } else {
            normalize_path(rel_path);
            add_to_file_array(arr, find_data.cFileName, rel_path);
        }
    } while (FindNextFileW(hFind, &find_data));
    
    FindClose(hFind);
}

// 转义特殊字符
wchar_t* escape_string(const wchar_t* input) {
    size_t len = wcslen(input);
    size_t escaped_len = len;
    
    // 计算需要转义的特殊字符数量
    for (const wchar_t* c = input; *c; c++) {
        if (*c == L'\"' || *c == L'\\') {
            escaped_len++;
        }
    }
    
    wchar_t* output = (wchar_t*)malloc((escaped_len + 1) * sizeof(wchar_t));
    wchar_t* p = output;
    
    for (const wchar_t* c = input; *c; c++) {
        if (*c == L'\"' || *c == L'\\') {
            *p++ = L'\\';
        }
        *p++ = *c;
    }
    *p = L'\0';
    
    return output;
}

// 生成C源文件（完全UTF-8编码）
void generate_c_file(const wchar_t *filename, const FileArray *arr,const wchar_t *pre_pth) {
    FILE *file;
    if (_wfopen_s(&file, filename, L"w, ccs=UTF-8") != 0) {
        fwprintf(stderr, L"无法创建文件: %s\n", filename);
        return;
    }
    
    // 写入BOM头
    fputc(0xEF, file);
    fputc(0xBB, file);
    fputc(0xBF, file);
    
    // 写入文件头
    fwprintf(file, L"#include <stdio.h>\n\n");
    fwprintf(file, L"// 文件信息二维数组（UTF-8编码）\n");
    fwprintf(file, L"const char *file_array[][3] = {\n");
    
    // 写入文件数据
    for (int i = 0; i < arr->count; i++) {
        // 转义特殊字符
        wchar_t* escaped_name = escape_string(arr->file_names[i]);
        wchar_t* escaped_path = escape_string(arr->rel_paths[i]);
        
         // 执行转换
    wchar_t* output = ConvertToTraditional(escaped_name);
   
        fwprintf(file, L"{\"%s\", \"%s\",\"%s%s\"},\n",escaped_name,output,pre_pth,escaped_path);
         if (output) {
            // wprintf(L"转换结果：%ls\n", output);
            free(output);  // 释放分配的内存
        } else {
            wprintf(L"转换失败\n");
        }
        free(escaped_name);
        free(escaped_path);

    }
    
    // 写入文件尾
    fwprintf(file, L"};\n\n");
    fwprintf(file, L"// 文件数量\n");
    fwprintf(file, L"#define FILE_COUNT %d\n\n", arr->count);
    fwprintf(file, L"// 打印文件列表\n");
    fwprintf(file, L"void print_file_list() {\n");
    fwprintf(file, L"    wprintf(L\"文件列表:\\n\");\n");
    fwprintf(file, L"    for (int i = 0; i < FILE_COUNT; i++) {\n");
    fwprintf(file, L"        wprintf(L\"文件: %%s\\n\", file_array[i][0]);\n");
    fwprintf(file, L"        wprintf(L\"路径: %%s\\n\\n\", file_array[i][1]);\n");
    fwprintf(file, L"    }\n");
    fwprintf(file, L"}\n\n");
    fwprintf(file, L"/*\n");
    fwprintf(file, L"int main() {\n");
    fwprintf(file, L"    // 设置控制台支持UTF-8输出\n");
    fwprintf(file, L"    _setmode(_fileno(stdout), _O_U8TEXT);\n");
    fwprintf(file, L"    print_file_list();\n");
    fwprintf(file, L"    return 0;\n");
    fwprintf(file, L"}\n");
    fwprintf(file, L"*/\n");
    
    fclose(file);
    wprintf(L"已生成C文件: %s\n", filename);
}

int main(int argc, char *argv[]) {
    // 设置控制台为UTF-8编码
    printf("程序名称: %s\n", argv[0]);
    printf("参数个数: %d\n", argc - 1);

    _setmode(_fileno(stdout), _O_U8TEXT);
    _setmode(_fileno(stderr), _O_U8TEXT);
    setlocale(LC_ALL, "zh_CN.UTF-8");
    
    s2t_init();
    // test_main();
    // 获取当前目录
    wchar_t current_dir[MAX_PATH];
    GetCurrentDirectoryW(MAX_PATH, current_dir);
    wprintf(L"扫描目录: %s\n", current_dir);
    
    FileArray arr;
    init_file_array(&arr, 100);
    
    scan_directory(current_dir, L"", &arr);
    wprintf(L"找到 %d 个文件\n", arr.count);

    wchar_t wchar[256] = {0};
	swprintf(wchar,256,L"%S",argv[1]);
    if((argc - 1)==0){
        swprintf(wchar,256,L"%S","");
    }

    generate_c_file(L"file_list.c", &arr,wchar);
    
    free_file_array(&arr);
    
    wprintf(L"按任意键退出...\n");
    _getwch();
    return 0;
}